/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package MiddleLayer.OtherClass;

import MiddleLayer.Cards;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author ThanhTri
 * - Lớp dùng để chứa dữ liệu đi lên đi xuống giữa các middle và network
 */
public class CommandStruct {
    
    static public String commandCode = "CMD";
    static public String chatCode = "CHA";
    static public String newPlayer = "NPL";//Có người chơi mới
    static public String quitCode = "QUI";
    static public String passCode = "PAS";
    static public String updateCardsCode = "UPC";//cập nhật toàn bộ danh sách bài
    static public String startPlayingCode = "PLA";//bắt đầu chơi
    static public String playCardCode = "PLC";//client chọn lá bài này để đi
    static public String newRoundCode = "NRC";//Lượt đi mới, client có id này sẽ đi đầu
    static public String newDealCode = "NDC";//Vòng đi mới, mỗi vòng gồm có nhiều lượt đi nhỏ

    /**
     * @return the iType
     */
    public MessageType getMessageType() {
        return iType;
    }

    public enum MessageType {

        Command,
        Chat,
        NewPlayer,//Thông điệp string sẽ chứa tên người chơi
        Quit,
        Pass,//các id sẽ cách nhau bởi 1 khoảng trắng
        UpdateCards,//Các id sẽ cách nhau bởi 1 khoảng trắng
        StartPlaying,//bắt đầu chơi
        PlayCard,//phía sau là id của lá bài sẽ đi
        NewRound,//Lượt đi mới, mỗi vòng gồm nhiều lượt đi
        NewDeal,//vòng đi mới
    };

    /*
     * Type 0: Command
     * Type 1: Chat
     */
    private MessageType iType = MessageType.Command;
    private String strContentOfMessage = null;
    private String seperateCharacter = " ";

    
    public CommandStruct(MessageType messageType, String content) {
        strContentOfMessage = content;
        iType = messageType;
    }

    /**
     * Thường gọi khi có lệnh PASS
     * @param id1
     * @param id2
     * @param id3
     */
    public CommandStruct(int id1, int id2, int id3)
    {
        this.iType = MessageType.Pass;
        this.strContentOfMessage = id1 + seperateCharacter + id2 + seperateCharacter + id3;
    }

    /**
     * Thường gọi khi có lệnh update cả bộ bài cho phía client
     * Tuy lớp cards có danh sách các lá ăn được
     * Nhưng không đưa xuống cho client biết mà chỉ giữ ở phía trên server sử dụng
     * @param id1
     * @param id2
     * @param id3
     */
    public CommandStruct(Cards cards)
    {
        this.iType = MessageType.Pass;
        List<Integer> cardLst = cards.getCardLst();
        for(int i = 0; i < cardLst.size() - 1; ++i)
        {
            this.strContentOfMessage += cardLst.get(i) + seperateCharacter;
        }
        this.strContentOfMessage += cardLst.get(cardLst.size() - 1);
    }

    public CommandStruct(String rawText)
    {
        if(rawText.startsWith(CommandStruct.chatCode))
            iType = MessageType.Chat;
        if(rawText.startsWith(CommandStruct.commandCode))
            iType = MessageType.Command;
        if(rawText.startsWith(CommandStruct.newPlayer))
            iType = MessageType.NewPlayer;
        if(rawText.startsWith(CommandStruct.quitCode))
            iType = MessageType.Quit;
        if(rawText.startsWith(CommandStruct.passCode))
            iType = MessageType.Pass;
        if(rawText.startsWith(CommandStruct.updateCardsCode))
            iType = MessageType.UpdateCards;
        if(rawText.startsWith(CommandStruct.startPlayingCode))
            iType = MessageType.StartPlaying;
        if(rawText.startsWith(CommandStruct.playCardCode))
            iType = MessageType.PlayCard;
        if(rawText.startsWith(CommandStruct.newDealCode))
            iType = MessageType.NewDeal;
        if(rawText.startsWith(CommandStruct.newRoundCode))
            iType = MessageType.NewRound;

        this.strContentOfMessage = rawText.substring(CommandStruct.chatCode.length());
    }

    /*
     * Thay đổi nội dung của gói tin command
     * Tương tự như hàm tạo public
     */
    public void changeCommand(String rawText)
    {
        if(rawText.startsWith(CommandStruct.chatCode))
            iType = MessageType.Chat;
        if(rawText.startsWith(CommandStruct.commandCode))
            iType = MessageType.Command;
        if(rawText.startsWith(CommandStruct.newPlayer))
            iType = MessageType.NewPlayer;
        if(rawText.startsWith(CommandStruct.quitCode))
            iType = MessageType.Quit;
        if(rawText.startsWith(CommandStruct.passCode))
            iType = MessageType.Pass;
        if(rawText.startsWith(CommandStruct.updateCardsCode))
            iType = MessageType.UpdateCards;
        if(rawText.startsWith(CommandStruct.playCardCode))
            iType = MessageType.PlayCard;
        if(rawText.startsWith(CommandStruct.newDealCode))
            iType = MessageType.NewDeal;
        if(rawText.startsWith(CommandStruct.newRoundCode))
            iType = MessageType.NewRound;

        this.strContentOfMessage = rawText.substring(CommandStruct.chatCode.length());
    }

    /**
     * @return Nội dung của gói lệnh
     */
    public String getContentOfMessage() {
        return strContentOfMessage;
    }

    /**
     * @param message the message to set
     */
    public void setMessage(String message) {
        this.strContentOfMessage = message;
    }

    /**
     * Kiểm tra loại của Message 1 cách tổng quát
     */
    public boolean isMessageType(MessageType messageType)
    {
        if(getMessageType() == messageType)
            return true;
        return false;
    }

    //Thông điệp này có phải là thông điệp chat không?
    public boolean isChatMessage()
    {
        if(getMessageType() == MessageType.Chat)
            return true;
        return false;
    }
    
    //Thông điệp này có phải là thông điệp chat không?
    public boolean isCommandMessage()
    {
        if(getMessageType() == MessageType.Command)
            return true;
        return false;
    }

    static public CommandStruct createNewPlayerCMDStruct(String clientName)
    {
        CommandStruct cmdStruct = new CommandStruct(MessageType.NewPlayer, clientName);
        return cmdStruct;
    }

    /**
     * @return Kiểu chuỗi chứa mã lệnh và nội dung của lệnh
     */
    @Override
    public String toString()
    {
        String result = "";

        switch(this.getMessageType())
        {
            case Chat:
                result = CommandStruct.chatCode;
                break;
            case Command:
                result = CommandStruct.commandCode;
                break;
            case NewPlayer:
                result = CommandStruct.newPlayer;
                break;
            case Quit:
                result = CommandStruct.quitCode;
                break;
            case Pass:
                result = CommandStruct.passCode;
                break;
            case PlayCard:
                result = CommandStruct.playCardCode;
                break;
            case StartPlaying:
                result = CommandStruct.startPlayingCode;
                break;
            case UpdateCards:
                result = CommandStruct.updateCardsCode;
                break;
            case NewDeal:
                result = CommandStruct.newDealCode;
                break;
            case NewRound:
                result = CommandStruct.newRoundCode;
                break;
        }

        return result + this.strContentOfMessage;
    }

    //Kiểm tra xem dữ liệu thô này có phải dữ liệu chat không
    static public boolean isChatMessage(String rawData)
    {
        if(rawData.startsWith(CommandStruct.chatCode))
            return true;
        return false;
    }

    //Kiểm tra xem dữ liệu thô này có phải dữ liệu chỉ thị không
    static public boolean isCommandMessage(String rawData)
    {
        if(rawData.startsWith(CommandStruct.commandCode))
            return true;
        return false;
    }

    //Kiểm tra xem dữ liệu thô này có phải lệnh quit hay không
    static public boolean isQuitMessage(String rawData)
    {
        if(rawData.startsWith(CommandStruct.quitCode))
            return true;
        return false;
    }


    //lấy ra mã code của thông điệp được gửi đến server
    static public String parseGetCode(String data){
        String result = new String();
        //result = String.copyValueOf(data.toCharArray(), 0, 3);
        result = data.substring(0, CommandStruct.quitCode.length());

        return result;
    }


    //Thông điệp được gửi đến có chứa mã kết thúc không?
    static public boolean isCommandQUIT(String data){
        if(data.startsWith(CommandStruct.quitCode, 0))
            return true;

        return false;
    }

    // trả về dữ liệu gốc ban đầu
    static public String getClearText(String data){
        return data.substring(CommandStruct.commandCode.length());
    }

    /**
     * Trả về các card sẽ được pass trong lượt chơi
     * @return
     */
    public List<Integer> getPassIDCards()
    {
        List<Integer> Result = new ArrayList<Integer>();

        if(this.iType == MessageType.Pass)
        {
            String tmp = this.strContentOfMessage;

            while(!tmp.equals(""))
            {
                int iIndex = tmp.indexOf(seperateCharacter);
                String number = tmp.substring(0, iIndex);
                tmp = tmp.substring(iIndex);

                Result.add(Integer.getInteger(number));
            }
        }

        return Result;

    }

    /**
     * Trả về các card được nhận mới từ phía server trong lượt chơi
     * Thường gọi khi bắt đầu ván bài hoặc sau khi PASS bài
     * @return
     */
    public List<Integer> getUpdateIDCards()
    {
        List<Integer> Result = new ArrayList<Integer>();

        if(this.iType == MessageType.UpdateCards)
        {
            String tmp = this.strContentOfMessage;

            while(!tmp.equals(""))
            {
                int iIndex = tmp.indexOf(seperateCharacter);
                String number = tmp.substring(0, iIndex);
                tmp = tmp.substring(iIndex);

                Result.add(Integer.getInteger(number));
            }
        }

        return Result;

    }
}
